/**
 * 错误定义
 *
 * Created by snowingsea on 2020/01/20.
 */
const utility = require('./utility');

/**
 * 自定义错误类
 */
class PhoenixError extends Error {
  /**
   * @param {String|Object} error 错误信息|错误类
   * @param {String} description 错误详细描述
   */
  constructor(error, description = null) {
    super();

    this.name = this.constructor.name;

    if (error instanceof PhoenixError) {
      this.message = error.message;
      this.description = error.description;
      this.stack = error.stack;
    } else if (error instanceof Error) {
      this.message = 'server error';
      this.description = error.message;
      this.stack = error.stack;
    } else {
      Error.captureStackTrace(this, this.constructor);
      this.message = error;
      this.description = description;
    }
    if (utility.isObjectType(this.message) || utility.isArrayType(this.message)) {
      this.message = JSON.stringify(this.message);
    }
    this.status = PhoenixError.statusCode(this.message);
  }

  /**
   * 转json格式
   * @return {Object}
   */
  toJSON() {
    return {
      name: this.name,
      message: this.message,
      description: this.description,
      status: this.status,
      stack: this.stack,
    };
  }

  /**
   * 状态码
   * @param {String} error 错误信息
   * @return {Number}
   */
  static statusCode(error) {
    switch (error) {
      case 'invalid request':
        return 400;
      case 'invalid grant':
      case 'invalid token':
        return 401;
      case 'forbidden':
        return 403;
      case 'not found':
        return 404;
      case 'conflict':
        return 409;
      case 'precondition failed':
        return 412;
      case 'over range':
        return 416;
      case 'resource locking':
        return 423;
      case 'frequent request':
        return 429;
      case 'No file to parse':
        return 430;
      case 'No files were parsed':
        return 431;
      case 'systemtime error':
        return 432;
      case 'No test case':
        return 433;
      case 'name already used':
        return 434;
      case 'no functions that have not been called':
        return 435;
      case 'git index lock':
        return 436;
      case 'code instrumentation frozen':
        return 437;
      case 'file format error':
        return 438;
      case 'function generation limit':
        return 442;
      case 'server error':
      default:
        return 500;
    }
  }
}

/**
 * Export model definition object.
 */
module.exports = PhoenixError;
